﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization;
using UnityEngine;

namespace UniRx
{
	// Token: 0x0200041B RID: 1051
	[Serializable]
	public class ReactiveDictionary<TKey, TValue> : IReactiveDictionary<TKey, TValue>, IDictionary<TKey, TValue>, IEnumerable, ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>, IDictionary, IDisposable, ISerializable, IDeserializationCallback, IReadOnlyReactiveDictionary<TKey, TValue>, ICollection
	{
		// Token: 0x060015A5 RID: 5541 RVA: 0x0005F90B File Offset: 0x0005DD0B
		public ReactiveDictionary()
		{
			this.inner = new Dictionary<TKey, TValue>();
		}

		// Token: 0x060015A6 RID: 5542 RVA: 0x0005F91E File Offset: 0x0005DD1E
		public ReactiveDictionary(IEqualityComparer<TKey> comparer)
		{
			this.inner = new Dictionary<TKey, TValue>(comparer);
		}

		// Token: 0x060015A7 RID: 5543 RVA: 0x0005F932 File Offset: 0x0005DD32
		public ReactiveDictionary(Dictionary<TKey, TValue> innerDictionary)
		{
			this.inner = innerDictionary;
		}

		// Token: 0x170001B1 RID: 433
		public TValue this[TKey key]
		{
			get
			{
				return this.inner[key];
			}
			set
			{
				TValue oldValue;
				if (this.TryGetValue(key, out oldValue))
				{
					this.inner[key] = value;
					if (this.dictionaryReplace != null)
					{
						this.dictionaryReplace.OnNext(new DictionaryReplaceEvent<TKey, TValue>(key, oldValue, value));
					}
				}
				else
				{
					this.inner[key] = value;
					if (this.dictionaryAdd != null)
					{
						this.dictionaryAdd.OnNext(new DictionaryAddEvent<TKey, TValue>(key, value));
					}
					if (this.countChanged != null)
					{
						this.countChanged.OnNext(this.Count);
					}
				}
			}
		}

		// Token: 0x170001B2 RID: 434
		// (get) Token: 0x060015AA RID: 5546 RVA: 0x0005F9E1 File Offset: 0x0005DDE1
		public int Count
		{
			get
			{
				return this.inner.Count;
			}
		}

		// Token: 0x170001B3 RID: 435
		// (get) Token: 0x060015AB RID: 5547 RVA: 0x0005F9EE File Offset: 0x0005DDEE
		public Dictionary<TKey, TValue>.KeyCollection Keys
		{
			get
			{
				return this.inner.Keys;
			}
		}

		// Token: 0x170001B4 RID: 436
		// (get) Token: 0x060015AC RID: 5548 RVA: 0x0005F9FB File Offset: 0x0005DDFB
		public Dictionary<TKey, TValue>.ValueCollection Values
		{
			get
			{
				return this.inner.Values;
			}
		}

		// Token: 0x060015AD RID: 5549 RVA: 0x0005FA08 File Offset: 0x0005DE08
		public void Add(TKey key, TValue value)
		{
			this.inner.Add(key, value);
			if (this.dictionaryAdd != null)
			{
				this.dictionaryAdd.OnNext(new DictionaryAddEvent<TKey, TValue>(key, value));
			}
			if (this.countChanged != null)
			{
				this.countChanged.OnNext(this.Count);
			}
		}

		// Token: 0x060015AE RID: 5550 RVA: 0x0005FA5C File Offset: 0x0005DE5C
		public void Clear()
		{
			int count = this.Count;
			this.inner.Clear();
			if (this.collectionReset != null)
			{
				this.collectionReset.OnNext(Unit.Default);
			}
			if (count > 0 && this.countChanged != null)
			{
				this.countChanged.OnNext(this.Count);
			}
		}

		// Token: 0x060015AF RID: 5551 RVA: 0x0005FABC File Offset: 0x0005DEBC
		public bool Remove(TKey key)
		{
			TValue value;
			if (this.inner.TryGetValue(key, out value))
			{
				bool flag = this.inner.Remove(key);
				if (flag)
				{
					if (this.dictionaryRemove != null)
					{
						this.dictionaryRemove.OnNext(new DictionaryRemoveEvent<TKey, TValue>(key, value));
					}
					if (this.countChanged != null)
					{
						this.countChanged.OnNext(this.Count);
					}
				}
				return flag;
			}
			return false;
		}

		// Token: 0x060015B0 RID: 5552 RVA: 0x0005FB2B File Offset: 0x0005DF2B
		public bool ContainsKey(TKey key)
		{
			return this.inner.ContainsKey(key);
		}

		// Token: 0x060015B1 RID: 5553 RVA: 0x0005FB39 File Offset: 0x0005DF39
		public bool TryGetValue(TKey key, out TValue value)
		{
			return this.inner.TryGetValue(key, out value);
		}

		// Token: 0x060015B2 RID: 5554 RVA: 0x0005FB48 File Offset: 0x0005DF48
		public Dictionary<TKey, TValue>.Enumerator GetEnumerator()
		{
			return this.inner.GetEnumerator();
		}

		// Token: 0x060015B3 RID: 5555 RVA: 0x0005FB58 File Offset: 0x0005DF58
		private void DisposeSubject<TSubject>(ref Subject<TSubject> subject)
		{
			if (subject != null)
			{
				try
				{
					subject.OnCompleted();
				}
				finally
				{
					subject.Dispose();
					subject = null;
				}
			}
		}

		// Token: 0x060015B4 RID: 5556 RVA: 0x0005FB94 File Offset: 0x0005DF94
		protected virtual void Dispose(bool disposing)
		{
			if (!this.disposedValue)
			{
				if (disposing)
				{
					this.DisposeSubject<int>(ref this.countChanged);
					this.DisposeSubject<Unit>(ref this.collectionReset);
					this.DisposeSubject<DictionaryAddEvent<TKey, TValue>>(ref this.dictionaryAdd);
					this.DisposeSubject<DictionaryRemoveEvent<TKey, TValue>>(ref this.dictionaryRemove);
					this.DisposeSubject<DictionaryReplaceEvent<TKey, TValue>>(ref this.dictionaryReplace);
				}
				this.disposedValue = true;
			}
		}

		// Token: 0x060015B5 RID: 5557 RVA: 0x0005FBF5 File Offset: 0x0005DFF5
		public void Dispose()
		{
			this.Dispose(true);
		}

		// Token: 0x060015B6 RID: 5558 RVA: 0x0005FC00 File Offset: 0x0005E000
		public IObservable<int> ObserveCountChanged()
		{
			if (this.isDisposed)
			{
				return Observable.Empty<int>();
			}
			Subject<int> result;
			if ((result = this.countChanged) == null)
			{
				result = (this.countChanged = new Subject<int>());
			}
			return result;
		}

		// Token: 0x060015B7 RID: 5559 RVA: 0x0005FC3C File Offset: 0x0005E03C
		public IObservable<Unit> ObserveReset()
		{
			if (this.isDisposed)
			{
				return Observable.Empty<Unit>();
			}
			Subject<Unit> result;
			if ((result = this.collectionReset) == null)
			{
				result = (this.collectionReset = new Subject<Unit>());
			}
			return result;
		}

		// Token: 0x060015B8 RID: 5560 RVA: 0x0005FC78 File Offset: 0x0005E078
		public IObservable<DictionaryAddEvent<TKey, TValue>> ObserveAdd()
		{
			if (this.isDisposed)
			{
				return Observable.Empty<DictionaryAddEvent<TKey, TValue>>();
			}
			Subject<DictionaryAddEvent<TKey, TValue>> result;
			if ((result = this.dictionaryAdd) == null)
			{
				result = (this.dictionaryAdd = new Subject<DictionaryAddEvent<TKey, TValue>>());
			}
			return result;
		}

		// Token: 0x060015B9 RID: 5561 RVA: 0x0005FCB4 File Offset: 0x0005E0B4
		public IObservable<DictionaryRemoveEvent<TKey, TValue>> ObserveRemove()
		{
			if (this.isDisposed)
			{
				return Observable.Empty<DictionaryRemoveEvent<TKey, TValue>>();
			}
			Subject<DictionaryRemoveEvent<TKey, TValue>> result;
			if ((result = this.dictionaryRemove) == null)
			{
				result = (this.dictionaryRemove = new Subject<DictionaryRemoveEvent<TKey, TValue>>());
			}
			return result;
		}

		// Token: 0x060015BA RID: 5562 RVA: 0x0005FCF0 File Offset: 0x0005E0F0
		public IObservable<DictionaryReplaceEvent<TKey, TValue>> ObserveReplace()
		{
			if (this.isDisposed)
			{
				return Observable.Empty<DictionaryReplaceEvent<TKey, TValue>>();
			}
			Subject<DictionaryReplaceEvent<TKey, TValue>> result;
			if ((result = this.dictionaryReplace) == null)
			{
				result = (this.dictionaryReplace = new Subject<DictionaryReplaceEvent<TKey, TValue>>());
			}
			return result;
		}

		// Token: 0x170001A7 RID: 423
		object IDictionary.this[object key]
		{
			get
			{
				return this[(TKey)((object)key)];
			}
			set
			{
				this[(TKey)((object)key)] = (TValue)((object)value);
			}
		}

		// Token: 0x170001A8 RID: 424
		// (get) Token: 0x060015BD RID: 5565 RVA: 0x0005FD50 File Offset: 0x0005E150
		bool IDictionary.IsFixedSize
		{
			get
			{
				return ((IDictionary)this.inner).IsFixedSize;
			}
		}

		// Token: 0x170001A9 RID: 425
		// (get) Token: 0x060015BE RID: 5566 RVA: 0x0005FD5D File Offset: 0x0005E15D
		bool IDictionary.IsReadOnly
		{
			get
			{
				return ((IDictionary)this.inner).IsReadOnly;
			}
		}

		// Token: 0x170001AA RID: 426
		// (get) Token: 0x060015BF RID: 5567 RVA: 0x0005FD6A File Offset: 0x0005E16A
		bool ICollection.IsSynchronized
		{
			get
			{
				return ((ICollection)this.inner).IsSynchronized;
			}
		}

		// Token: 0x170001AB RID: 427
		// (get) Token: 0x060015C0 RID: 5568 RVA: 0x0005FD77 File Offset: 0x0005E177
		ICollection IDictionary.Keys
		{
			get
			{
				return ((IDictionary)this.inner).Keys;
			}
		}

		// Token: 0x170001AC RID: 428
		// (get) Token: 0x060015C1 RID: 5569 RVA: 0x0005FD84 File Offset: 0x0005E184
		object ICollection.SyncRoot
		{
			get
			{
				return ((ICollection)this.inner).SyncRoot;
			}
		}

		// Token: 0x170001AD RID: 429
		// (get) Token: 0x060015C2 RID: 5570 RVA: 0x0005FD91 File Offset: 0x0005E191
		ICollection IDictionary.Values
		{
			get
			{
				return ((IDictionary)this.inner).Values;
			}
		}

		// Token: 0x170001AE RID: 430
		// (get) Token: 0x060015C3 RID: 5571 RVA: 0x0005FD9E File Offset: 0x0005E19E
		bool ICollection<KeyValuePair<TKey, TValue>>.IsReadOnly
		{
			get
			{
				return ((ICollection<KeyValuePair<TKey, TValue>>)this.inner).IsReadOnly;
			}
		}

		// Token: 0x170001AF RID: 431
		// (get) Token: 0x060015C4 RID: 5572 RVA: 0x0005FDAB File Offset: 0x0005E1AB
		ICollection<TKey> IDictionary<TKey, TValue>.Keys
		{
			get
			{
				return this.inner.Keys;
			}
		}

		// Token: 0x170001B0 RID: 432
		// (get) Token: 0x060015C5 RID: 5573 RVA: 0x0005FDB8 File Offset: 0x0005E1B8
		ICollection<TValue> IDictionary<TKey, TValue>.Values
		{
			get
			{
				return this.inner.Values;
			}
		}

		// Token: 0x060015C6 RID: 5574 RVA: 0x0005FDC5 File Offset: 0x0005E1C5
		void IDictionary.Add(object key, object value)
		{
			this.Add((TKey)((object)key), (TValue)((object)value));
		}

		// Token: 0x060015C7 RID: 5575 RVA: 0x0005FDD9 File Offset: 0x0005E1D9
		bool IDictionary.Contains(object key)
		{
			return ((IDictionary)this.inner).Contains(key);
		}

		// Token: 0x060015C8 RID: 5576 RVA: 0x0005FDE7 File Offset: 0x0005E1E7
		void ICollection.CopyTo(Array array, int index)
		{
			((ICollection)this.inner).CopyTo(array, index);
		}

		// Token: 0x060015C9 RID: 5577 RVA: 0x0005FDF6 File Offset: 0x0005E1F6
		public void GetObjectData(SerializationInfo info, StreamingContext context)
		{
			((ISerializable)this.inner).GetObjectData(info, context);
		}

		// Token: 0x060015CA RID: 5578 RVA: 0x0005FE05 File Offset: 0x0005E205
		public void OnDeserialization(object sender)
		{
			((IDeserializationCallback)this.inner).OnDeserialization(sender);
		}

		// Token: 0x060015CB RID: 5579 RVA: 0x0005FE13 File Offset: 0x0005E213
		void IDictionary.Remove(object key)
		{
			this.Remove((TKey)((object)key));
		}

		// Token: 0x060015CC RID: 5580 RVA: 0x0005FE22 File Offset: 0x0005E222
		void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> item)
		{
			this.Add(item.Key, item.Value);
		}

		// Token: 0x060015CD RID: 5581 RVA: 0x0005FE38 File Offset: 0x0005E238
		bool ICollection<KeyValuePair<TKey, TValue>>.Contains(KeyValuePair<TKey, TValue> item)
		{
			return ((ICollection<KeyValuePair<TKey, TValue>>)this.inner).Contains(item);
		}

		// Token: 0x060015CE RID: 5582 RVA: 0x0005FE46 File Offset: 0x0005E246
		void ICollection<KeyValuePair<TKey, TValue>>.CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
		{
			((ICollection<KeyValuePair<TKey, TValue>>)this.inner).CopyTo(array, arrayIndex);
		}

		// Token: 0x060015CF RID: 5583 RVA: 0x0005FE55 File Offset: 0x0005E255
		IEnumerator<KeyValuePair<TKey, TValue>> IEnumerable<KeyValuePair<TKey, TValue>>.GetEnumerator()
		{
			return ((IEnumerable<KeyValuePair<TKey, TValue>>)this.inner).GetEnumerator();
		}

		// Token: 0x060015D0 RID: 5584 RVA: 0x0005FE62 File Offset: 0x0005E262
		IEnumerator IEnumerable.GetEnumerator()
		{
			return this.inner.GetEnumerator();
		}

		// Token: 0x060015D1 RID: 5585 RVA: 0x0005FE74 File Offset: 0x0005E274
		bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> item)
		{
			TValue x;
			if (this.TryGetValue(item.Key, out x) && EqualityComparer<TValue>.Default.Equals(x, item.Value))
			{
				this.Remove(item.Key);
				return true;
			}
			return false;
		}

		// Token: 0x060015D2 RID: 5586 RVA: 0x0005FEBD File Offset: 0x0005E2BD
		IDictionaryEnumerator IDictionary.GetEnumerator()
		{
			return ((IDictionary)this.inner).GetEnumerator();
		}

		// Token: 0x04000C64 RID: 3172
		[NonSerialized]
		private bool isDisposed;

		// Token: 0x04000C65 RID: 3173
		[SerializeField]
		private readonly Dictionary<TKey, TValue> inner;

		// Token: 0x04000C66 RID: 3174
		private bool disposedValue;

		// Token: 0x04000C67 RID: 3175
		[NonSerialized]
		private Subject<int> countChanged;

		// Token: 0x04000C68 RID: 3176
		[NonSerialized]
		private Subject<Unit> collectionReset;

		// Token: 0x04000C69 RID: 3177
		[NonSerialized]
		private Subject<DictionaryAddEvent<TKey, TValue>> dictionaryAdd;

		// Token: 0x04000C6A RID: 3178
		[NonSerialized]
		private Subject<DictionaryRemoveEvent<TKey, TValue>> dictionaryRemove;

		// Token: 0x04000C6B RID: 3179
		[NonSerialized]
		private Subject<DictionaryReplaceEvent<TKey, TValue>> dictionaryReplace;
	}
}
